package com.huanke.iot.job.stat;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.huanke.iot.base.dao.device.DeviceDataHistoryMapper;
import com.huanke.iot.base.dao.device.DeviceMapper;
import com.huanke.iot.base.dao.device.data.DeviceSensorDataMapper;
import com.huanke.iot.base.dao.device.typeModel.DeviceModelAbilityMapper;
import com.huanke.iot.base.dao.methodInfo.MethodAlarmMapper;
import com.huanke.iot.base.dao.methodInfo.MethodLogMapper;
import com.huanke.iot.base.po.Alarms.Alarms;
import com.huanke.iot.base.po.device.DeviceDataHistoryPo;
import com.huanke.iot.base.po.device.DevicePo;
import com.huanke.iot.base.po.device.typeModel.DeviceModelAbilityPo;
import com.huanke.iot.base.po.methodInfo.MethodAlarm;
import com.huanke.iot.base.po.methodInfo.MethodLog;
import com.huanke.iot.base.util.HttpClientUtil;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.DefaultThreadFactory;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;

/**
 * @author haoshijing
 * @version 2018年05月16日 20:27
 **/

@Repository
@Slf4j
public class DeviceSensorStatWorkerNew {

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private DeviceSensorDataMapper deviceSensorDataMapper;

    @Autowired
    private DeviceModelAbilityMapper deviceModelAbilityMapper;
    @Autowired
    private DeviceDataHistoryMapper deviceDataHistoryMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Autowired
    private MethodLogMapper methodLogMapper;

    @Autowired
    private MethodAlarmMapper methodAlarmMapper;

    @Value("${addAlarmsUrl}")
    private String addAlarmsUrl;

    private DefaultEventExecutorGroup defaultEventExecutorGroup = new DefaultEventExecutorGroup(16,
            new DefaultThreadFactory("NewStatSensorThread"));

    @Scheduled(cron = "0 10/30 * * * ?")
    public void doWork(){
        log.info("DeviceSensorStatWorkerNew start work");
        DevicePo queryPo = new DevicePo();
        int offset = 0;
        List<DevicePo> devicePoList = deviceMapper.selectList(queryPo, 100, offset);
        final Long startTime = new DateTime().withMillisOfSecond(0).plusMinutes(-40).getMillis();
        final Long endTime = new DateTime().withMillisOfSecond(0).plusMinutes(-10).getMillis();
        do {
            devicePoList.forEach(devicePo -> {
                //方法异常对象信息
                JSONObject infoJson = new JSONObject();
                //未被分配的设备不记录
                Integer customerId = devicePo.getCustomerId();
                Integer modelId = devicePo.getModelId();
                Integer deviceId = devicePo.getId();
                if(customerId == null){
                    return;
                }
                List<DeviceModelAbilityPo> deviceModelAbilityPos = deviceModelAbilityMapper.selectByIsCheck(modelId);

                JSONArray jsonArray = new JSONArray();
                infoJson.put("deviceId",deviceId);
                infoJson.put("modelId",modelId);
                infoJson.put("deviceModelAbilityPos.isEmpty",deviceModelAbilityPos.isEmpty());
                for (DeviceModelAbilityPo deviceModelAbilityPo : deviceModelAbilityPos) {
                    try {
                        String abilityHisDir = deviceModelAbilityPo.getDirValue();
                        String abilityHisValue  = (String) stringRedisTemplate.opsForHash().get("sensor2." + deviceId, abilityHisDir);
                        if(abilityHisValue == null){
                            abilityHisValue = (String) stringRedisTemplate.opsForHash().get("control2." + deviceId, abilityHisDir);
                        }
                        if(abilityHisValue == null){
                            abilityHisValue = "0";
                        }
                        JSONObject jb = new JSONObject();
                        jb.put("dir", abilityHisDir);
                        jb.put("dirValue", abilityHisValue);
                        jsonArray.add(jb);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (!jsonArray.isEmpty()){
                    DeviceDataHistoryPo deviceDataHistoryPo = new DeviceDataHistoryPo(deviceId, jsonArray.toJSONString(), new Date());
                    deviceDataHistoryMapper.insert(deviceDataHistoryPo);
                }else{
                    HttpClientUtil.sendPostDataByClass(addAlarmsUrl,new Alarms("job","stat.DeviceSensorStatWorkerNew.doWork",infoJson.toString(),"hisDir为空",3));
                }
            });

            offset += devicePoList.size();
            devicePoList = deviceMapper.selectList(queryPo, 100, offset);
        } while (devicePoList.size() > 0);
        log.info("DeviceSensorStatWorker end work");

        MethodLog methodLog = new MethodLog("com.huanke.iot.job.stat.DeviceSensorStatWorkerNew","doWork",startTime,System.currentTimeMillis(),1,"","");
        methodLogMapper.insert(methodLog);
    }

    @Scheduled(cron = "0 10/30 * * * ?")
    public void doWork1() {
        log.info("ChildDeviceSensorStatWorkerNew start work");
        DevicePo queryPo = new DevicePo();
        /*int offset = 0;
        List<DevicePo> devicePoList = deviceMapper.selectChildList(queryPo, 100, offset);*/

        List<DevicePo> devicePoList = deviceMapper.selectChildListUnlimit(queryPo);

        final Long startTime = new DateTime().withMillisOfSecond(0).plusMinutes(-40).getMillis();
        final Long endTime = new DateTime().withMillisOfSecond(0).plusMinutes(-10).getMillis();
        //去除分页限制
        /*do {*/
            devicePoList.forEach(devicePo -> {
                //未被分配的设备不记录
                Integer customerId = devicePo.getCustomerId();
                Integer deviceId = devicePo.getId();

                Integer modelId = devicePo.getModelId();
                /*if(customerId == null){
                    return;
                }*/
                List<DeviceModelAbilityPo> deviceModelAbilityPos = deviceModelAbilityMapper.selectByIsCheck(modelId);
                JSONArray jsonArray = new JSONArray();
                for (DeviceModelAbilityPo deviceModelAbilityPo : deviceModelAbilityPos) {
                    try {
                        String abilityHisDir = deviceModelAbilityPo.getDirValue();
                        String abilityHisValue  = (String) stringRedisTemplate.opsForHash().get("sensor2." + deviceId, abilityHisDir);
                        if(abilityHisValue == null){
                            abilityHisValue = (String) stringRedisTemplate.opsForHash().get("control2." + deviceId, abilityHisDir);
                        }
                        if(abilityHisValue == null){
                            abilityHisValue = "0";
                        }
                        JSONObject jb = new JSONObject();
                        jb.put("dir", abilityHisDir);
                        jb.put("dirValue", abilityHisValue);
                        jsonArray.add(jb);
                    } catch (Exception e) {

                        e.printStackTrace();
                    }
                }
                if(!jsonArray.toJSONString().equals("[]")){
                    DeviceDataHistoryPo deviceDataHistoryPo = new DeviceDataHistoryPo(deviceId, jsonArray.toJSONString(), new Date());
                    deviceDataHistoryMapper.insert(deviceDataHistoryPo);
                }
            });

            /*offset += devicePoList.size();
            devicePoList = deviceMapper.selectChildList(queryPo, 100, offset);
        } while (devicePoList.size() > 0);*/
        log.info("ChildDeviceSensorStatWorker end work");
    }

    @AllArgsConstructor
    @NoArgsConstructor
    class QueryTask implements Callable<Float> {

        private Integer deviceId;
        private Long startTime;
        private Long endTime;
        private String type;

        @Override
        public Float call() throws Exception {
            Float data = deviceSensorDataMapper.selectAvgData(deviceId, startTime, endTime,
                    String.valueOf(type));
            if (data == null) {
                data = Float.parseFloat((String) stringRedisTemplate.opsForHash().get("sensor2." + deviceId, type));
            }
            if(data == null){
                data = Float.parseFloat((String) stringRedisTemplate.opsForHash().get("control2." + deviceId, type));
            }
            if(data == null){
                data = 0F;
            }
            return data;
        }
    }
}
